﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using GBlog.Core.Service;

namespace GBlog.Core
{

    public class GViewEngine : RazorViewEngine
    {
        private IThemeService themeService = null;
        private String lastTheme = String.Empty;

        private String[] amlf = null;
        private String[] apvlf = null;
        private String[] avlf = null;
        private String[] mlf = null;
        private String[] pvlf = null;
        private String[] vlf = null;

        public GViewEngine() : base() { this.StoreDefaultFormats(); }

        public GViewEngine(IThemeService themeService) : base() { this.themeService = themeService; this.StoreDefaultFormats(); }

        private IThemeService ThemeService
        {
            get
            {
                if (this.themeService == null)
                {
                    this.themeService = DependencyResolver.Current.GetService<IThemeService>();
                }
                return this.themeService;
            }
        }

        private void StoreDefaultFormats()
        {
            this.pvlf = base.PartialViewLocationFormats;
            this.mlf = base.MasterLocationFormats;
            this.vlf = base.ViewLocationFormats;
            this.amlf = base.AreaMasterLocationFormats;
            this.apvlf = base.AreaPartialViewLocationFormats;
            this.avlf = base.AreaViewLocationFormats;
        }

        private void UpdateLocations(ControllerContext controllerContext)
        {
            string theme = ThemeService.GetCurrentTheme();
            if (!string.IsNullOrWhiteSpace(theme))
            {
                if (lastTheme != theme)
                {
                    string themeBasePath = this.ThemeService.GetThemeBaseURL(theme);
                    if (!string.IsNullOrWhiteSpace(themeBasePath))
                    {
                        string[] themeLocations = new string[] 
                        { 
							string.Format("{0}{1}", themeBasePath, "Views/{1}/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Views/{1}/{0}.vbhtml"),
							string.Format("{0}{1}", themeBasePath, "Views/Shared/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Views/Shared/{0}.vbhtml"),
							string.Format("{0}{1}", themeBasePath, "Views/Shared/{1}/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Views/Shared/{1}/{0}.vbhtml")
						};

                        string[] themeAreaLocations = new string[] 
                        { 
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/{1}/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/{1}/{0}.vbhtml"),
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/Shared/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/Shared/{0}.vbhtml"),
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/Shared/{1}/{0}.cshtml"),
							string.Format("{0}{1}", themeBasePath, "Areas/{2}/Views/Shared/{1}/{0}.vbhtml")
						};

                        this.AreaMasterLocationFormats = themeAreaLocations.Union(amlf).ToArray();
                        this.AreaPartialViewLocationFormats = themeAreaLocations.Union(apvlf).ToArray();
                        this.AreaViewLocationFormats = themeAreaLocations.Union(avlf).ToArray();
                        this.MasterLocationFormats = themeLocations.Union(mlf).ToArray();
                        this.PartialViewLocationFormats = themeLocations.Union(pvlf).ToArray();
                        this.ViewLocationFormats = themeLocations.Union(vlf).ToArray();
                        lastTheme = theme;
                    }
                }
            }
            else
            {
                this.AreaMasterLocationFormats = amlf;
                this.AreaPartialViewLocationFormats = apvlf;
                this.AreaViewLocationFormats = avlf;
                this.MasterLocationFormats = mlf;
                this.PartialViewLocationFormats = pvlf;
                this.ViewLocationFormats = vlf;
                lastTheme = string.Empty;
            }
        }

        public override ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            this.UpdateLocations(controllerContext);
            return base.FindPartialView(controllerContext, partialViewName, useCache);
        }

        public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            this.UpdateLocations(controllerContext);
            return base.FindView(controllerContext, viewName, masterName, useCache);
        }

        protected override bool FileExists(ControllerContext controllerContext, string virtualPath)
        {
            bool result = base.FileExists(controllerContext, virtualPath);
            return result;
        }
    }
}